﻿using System;
using System.Collections.Generic;
using System.Text;

namespace ycdlib
{
	public delegate YCNode NodeCreator ( YCNode parent );
//	public delegate YCNode ValueParse ( YCNode parent, string type, string name, string id, Parser p );

	/// <summary>
	/// ドキュメント読み込み設定
	/// </summary>
	public class YCReaderSetting
	{
		#region フィールド

		internal Encoding	enc;
		internal Dictionary<string, NodeCreator> yctypes;

		#endregion

		#region プロパティ

		/// <summary>
		/// 文字エンコーディングを取得、または設定できる
		/// </summary>
		public Encoding Encoding
		{
			get { return enc; }
			set { enc = value; }
		}


		/// <summary>
		/// 型の名前を指定して、値パーサーを取得できる
		/// </summary>
		/// <param name="k"></param>
		/// <returns></returns>
		public NodeCreator this[ string k ]
		{
			get { return yctypes[k]; }
		}

		#endregion


		/// <summary>
		/// コンストラクタ
		/// </summary>
		internal YCReaderSetting ()
		{
			enc = Encoding.UTF8;
			yctypes = new Dictionary<string,NodeCreator>();

			yctypes.Add( "int", YCNodeInt.CreateNode );
			yctypes.Add( "float", YCNodeFloat.CreateNode );
			yctypes.Add( "string", YCNodeString.CreateNode );
		}


		/// <summary>
		/// 型を追加する
		/// </summary>
		/// <param name="name"></param>
		/// <param name="parserFunc"></param>
		public void AddYCType ( string name, NodeCreator parserFunc )
		{
			yctypes.Add( name, parserFunc );
		}


		/// <summary>
		/// 型の名前を指定して、値パーサーの取得を試みる
		/// </summary>
		/// <param name="k">型の名前</param>
		/// <param name="vp">値パーサー</param>
		/// <returns></returns>
		public bool TryGetCreator ( string k, out NodeCreator nc )
		{
			return yctypes.TryGetValue( k, out nc );
		}


		/// <summary>
		/// YCノードを作成する
		/// </summary>
		/// <param name="parent"></param>
		/// <param name="type"></param>
		/// <param name="name"></param>
		/// <param name="id"></param>
		/// <returns></returns>
		internal YCNode CreateNode( YCNode parent, string type, string name, string id )
		{
			NodeCreator nc = null;
			YCNode __result = null;
			if( yctypes.TryGetValue( type, out nc ) )
			{
				__result = nc.Invoke( parent );
			}else
			{
				__result = new YCNodeAnother( type, parent );
			}
			__result.Name = name;
			__result.ID = id;
			return __result;
		}
	}
}
